package project

import (
	"goskeleton/app/global/variable"
	"goskeleton/app/model"
	"goskeleton/app/utils/data_bind"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func CreateProjectFactory(sqlType string) *ProjectModel {
	return &ProjectModel{BaseModel: model.BaseModel{DB: model.UseDbConn(sqlType)}}
}

type ProjectModel struct {
	model.BaseModel
	ProjectName             string `gorm:"column:project_name" json:"project_name"`
	Description             string `gorm:"column:description" json:"description"`
	ClientId                int    `gorm:"column:client_id" json:"client_id"`
	ResponsibleEmployeeId   int    `gorm:"column:responsible_employee_id" json:"responsible_employee_id"`
	ResponsibleDepartmentId int    `gorm:"column:responsible_department_id" json:"responsible_department_id"`
	StartDate               string `gorm:"column:start_date" json:"start_date"`
	ExpectedEndDate         string `gorm:"column:expected_end_date" json:"expected_end_date"`
	Progress                int    `gorm:"column:progress" json:"progress"`
	CreatedAt               string `gorm:"column:created_at" json:"created_at"`
	UpdatedAt               string `gorm:"column:updated_at" json:"updated_at"`
	CustomerName            string `gorm:"-" json:"customer_name"`   // 添加这个字段，用于返回客户名称
	EmployeeName            string `gorm:"-" json:"employee_name"`   // 添加这个字段，用于返回员工名称
	DepartmentName          string `gorm:"-" json:"department_name"` // 添加这个字段，用于返回部门名称
	DeleteStatus            int    `gorm:"column:delete_status" json:"delete_status"` // 是否删除 1否 2是
}

// ProjectModel sets the name of the table in the database
func (p *ProjectModel) TableName() string {
	return "tb_project"
}

func (p *ProjectModel) InsertData(c *gin.Context) bool {
	var tmp ProjectModel
	if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
		if res := p.Create(&tmp); res.Error == nil {
			return true
		} else {
			variable.ZapLog.Error("ProjectModel 数据新增出错", zap.Error(res.Error))
		}
	} else {
		variable.ZapLog.Error("ProjectModel 数据绑定出错", zap.Error(err))
	}
	return false
}

// 根据关键词查询用户表的条数
func (p *ProjectModel) getCounts() (counts int64) {
	sql := "select  count(*) as counts from tb_project"
	if _ = p.Raw(sql).First(&counts); counts > 0 {
		return counts
	} else {
		return 0
	}
}

func (p *ProjectModel) getCountsByWhere(
	projectName string, 
	responsibleEmployeeId int, 
	responsibleDepartmentId []int, 
	progress int, 
	expectedStartDateStart string, 
	expectedStartDateEnd string, 
	expectedEndDateStart string, 
	expectedEndDateEnd string,
) (counts int64) {
	query := p.Model(&ProjectModel{})
	if projectName != "" {
		query = query.Where("project_name like ?", "%"+projectName+"%")
	}
	if responsibleEmployeeId > 0 {
		query = query.Where("responsible_employee_id = ?", responsibleEmployeeId)
	}
	if len(responsibleDepartmentId) > 0 {
		query = query.Where("responsible_department_id in (?)", responsibleDepartmentId)
	}
	if progress > 0 {
		query = query.Where("progress = ?", progress)
	}
	if expectedStartDateStart != "" {
		query = query.Where("start_date >= ?", expectedStartDateStart)
	}
	if expectedStartDateEnd != "" {
		query = query.Where("start_date <= ?", expectedStartDateEnd)
	}
	if expectedEndDateStart != "" {
		query = query.Where("expected_end_date >= ?", expectedEndDateStart)
	}
	if expectedEndDateEnd != "" {
		query = query.Where("expected_end_date <= ?", expectedEndDateEnd)
	}
	query = query.Where("delete_status = ?", 1)
	query.Count(&counts)

	return counts

}

func (p *ProjectModel) UpdateData(c *gin.Context) bool {
	var tmp ProjectModel
	if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
		if res := p.Updates(&tmp); res.Error == nil {
			return true
		} else {
			variable.ZapLog.Error("ProjectModel 数据更新出错", zap.Error(res.Error))
			return false

		}
	} else {
		variable.ZapLog.Error("ProjectModel 数据绑定出错", zap.Error(err))
	}
	return false

}

func (p *ProjectModel) ListData(
	page,
	limitItems int,
	order string,
	projectName string,
	responsibleEmployeeId int,
	responsibleDepartmentId []int,
	progress int,
	expectedStartDateStart string,
	expectedStartDateEnd string,
	expectedEndDateStart string,
	expectedEndDateEnd string,
) (totalCounts int64, tmp []*ProjectModel) {
	// var tmp []*ProjectModel
	counts := p.getCountsByWhere(
		projectName, 
		responsibleEmployeeId, 
		responsibleDepartmentId, 
		progress, 
		expectedStartDateStart, 
		expectedStartDateEnd, 
		expectedEndDateStart, 
		expectedEndDateEnd,
	)
	
	if counts == 0 {
		return 0, nil
	}
	query:=p.Model(&ProjectModel{})

	if projectName != "" {
		query = query.Where("project_name like ?", "%"+projectName+"%")
	}
	if responsibleEmployeeId > 0 {
		query = query.Where("responsible_employee_id = ?", responsibleEmployeeId)
	}
	if len(responsibleDepartmentId) > 0 {
		query = query.Where("responsible_department_id in (?)", responsibleDepartmentId)
	}
	if progress > 0 {
		query = query.Where("progress = ?", progress)
	}
	if expectedStartDateStart != "" {
		query = query.Where("start_date >= ?", expectedStartDateStart)
	}
	if expectedStartDateEnd != "" {
		query = query.Where("start_date <= ?", expectedStartDateEnd)
	}
	if expectedEndDateStart != "" {
		query = query.Where("expected_end_date >= ?", expectedEndDateStart)
	}
	if expectedEndDateEnd != "" {
		query = query.Where("expected_end_date <= ?", expectedEndDateEnd)
	}
	query = query.Where("delete_status = ?", 1)

	if res := query.Limit(limitItems).Offset(page).Order(order).Find(&tmp); res.Error == nil {
		
		return counts, tmp

	} else {
		variable.ZapLog.Error("ProjectModel 数据查询失败", zap.Error(res.Error))
	}
	return 0, nil
}

func (p *ProjectModel) ShowOneItem(id int) (tmp *ProjectModel) {
	if res := p.Where("id = ?", id).First(&tmp); res.Error == nil && tmp.Id > 0 {

		return tmp
	} else {
		variable.ZapLog.Error("ProjectModel 数据查询出错", zap.Error(res.Error))
	}
	return nil

}

func (p *ProjectModel) GetProjectByIds(ids []int) (tmp []*ProjectModel) {
	if res := p.Where("id in (?)", ids).Where("delete_status = ?", 1).Find(&tmp); res.Error == nil {
		return tmp
	}
	return nil
}

func (p *ProjectModel) GetTotalProgressStatistics() (totalProgressStatistics *TotalStatusStatistics) {
	var tmp []*TotalStatusStatistics
	query := p.Model(p)
	query.Select("sum(case when progress = 0 then 1 else 0 end) as not_started,sum(case when progress = 1 then 1 else 0 end) as in_progress,sum(case when progress = 2 then 1 else 0 end) as completed")
	if err := query.First(&tmp).Error; err != nil {
		variable.ZapLog.Error("ProjectModel 数据查询出错", zap.Error(err))
	}
	if len(tmp) > 0 {
		totalProgressStatistics = tmp[0]
	}
	return totalProgressStatistics
}

func (p *ProjectModel) GetAllProjectName() (tmp  []*SearchProject) {
	if res := p.Model(p).Where("delete_status = ?", 1).Find(&tmp); res.Error == nil {
		return tmp
	}
	return nil
}

func (p *ProjectModel) DeleteData(id int) bool {
	if res := p.Model(p).Where("id = ?", id).Updates(map[string]interface{}{"delete_status": 2}); res.Error == nil {
		return true
	} else {
		variable.ZapLog.Error("ProjectModel DeleteData 数据更新出错", zap.Int("id", id), zap.Error(res.Error))
	}
	return false
}
